﻿
using Microsoft.AspNetCore.Hosting;
using System.Web;

namespace MyFurion.Application.Controller
{
    /// <summary>
    /// 附件
    /// </summary>
    public class FileController:IDynamicApiController
    {
        private readonly FileRepository _repository;
        private readonly IWebHostEnvironment _environment;
        public FileController(FileRepository repository, IWebHostEnvironment environment)
        {
            _repository = repository;
            _environment = environment;
        }
        /// <summary>
        /// 上传多附件—本地存储
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<List<SysFile>> UploadFiles([FromForm] IFormCollection formData)
        {
            List<SysFile> attachFiles = new List<SysFile>();//返回的附件上传结果
            IFormFileCollection formFiles = formData.Files;//获取上传的文件
            if (formFiles == null || formFiles.Count == 0)
            {
                throw Oops.Oh("请选择需要上传的文件！");
            }
            else
            {
                foreach (IFormFile formFile in formFiles)
                {
                    string fileExtension = Path.GetExtension(formFile.FileName);//获取文件名称后缀                                                                                                 
                    // 保存到网站根目录下的 uploads 目录
                    var savePath = Path.Combine(_environment.WebRootPath, @"uploads\" + DateTime.Now.ToString("yyyyMMdd"));
                    if (!Directory.Exists(savePath))
                    {
                        Directory.CreateDirectory(savePath);
                    }
                    // 避免文件名重复，采用 GUID 生成
                    var filePath = Path.Combine(savePath, Guid.NewGuid().ToString("N") + fileExtension);  // 可以替代为你需要存储的真实路径
                    using (var stream = File.Create(filePath))
                    {
                        await formFile.CopyToAsync(stream);
                    }
                    attachFiles.Add(new SysFile()
                    {
                        FileName = formFile.FileName,
                        FileType = fileExtension,
                        FileSize = ToolUtil.FormatFileSize(formFile.Length),
                        SaveType = EnumFileSaveType.Local,
                        FilePath = filePath.Replace(_environment.WebRootPath, "")                       
                    });                 
                }
                await _repository.Insert(attachFiles);
            }
            return attachFiles;
        }
        /// <summary>
        /// 上传单附件—本地存储
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<SysFile> UploadFile(IFormFile formFile)
        {
            SysFile attachFile = null;//返回的附件上传结果
            if (formFile == null)
            {
                throw Oops.Oh("请选择需要上传的文件！");
            }
            else
            {
                string fileExtension = Path.GetExtension(formFile.FileName);//获取文件名称后缀                                                                                                 
                // 保存到网站根目录下的 uploads 目录
                var savePath = Path.Combine(_environment.WebRootPath, @"uploads\" + DateTime.Now.ToString("yyyyMMdd"));
                if (!Directory.Exists(savePath))
                {
                    Directory.CreateDirectory(savePath);
                }
                // 避免文件名重复，采用 GUID 生成
                var filePath = Path.Combine(savePath, Guid.NewGuid().ToString("N") + fileExtension);  // 可以替代为你需要存储的真实路径
                using (var stream = File.Create(filePath))
                {
                    await formFile.CopyToAsync(stream);
                }
                attachFile = new SysFile()
                {
                    FileName = formFile.FileName,
                    FileType = fileExtension,
                    FileSize = ToolUtil.FormatFileSize(formFile.Length),
                    SaveType = EnumFileSaveType.Local,
                    FilePath = filePath.Replace(_environment.WebRootPath, "")
                };
                await _repository.Insert(attachFile);
            }
            return attachFile;
        }
        /// <summary>
        /// 上传多附件—Ftp存储
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<List<SysFile>> UploadFtpFiles([FromForm] IFormCollection formData)
        {
            var configuration = App.Configuration;
            string ftpUrl = configuration["FileFtp:FtpUrl"];//App.GetConfig<string>("FileFtp:FtpUrl")
            string ftpUser = configuration["FileFtp:FtpUser"];
            string ftpPassWord = configuration["FileFtp:FtpPwd"];
            List<SysFile> attachFiles = new List<SysFile>();//返回的附件上传结果
            IFormFileCollection formFiles = formData.Files;//获取上传的文件
            if (formFiles == null || formFiles.Count == 0)
            {
                throw Oops.Oh("请选择需要上传的文件！");
            }
            else
            {
                List<string> error = new();
                foreach (IFormFile formFile in formFiles)
                {
                    string fileExtension = Path.GetExtension(formFile.FileName);//获取文件名称后缀                                                                                                 
                    string savePath = "";
                    var fileStream = formFile.OpenReadStream();
                    bool saveResult = FileHelper.FTPUploadFile(fileStream, fileExtension, ftpUrl, ftpUser, ftpPassWord, out savePath);
                    if (saveResult)
                    {
                        attachFiles.Add(new SysFile()
                        {
                            FileName = formFile.FileName,
                            FileType = fileExtension,
                            FileSize = ToolUtil.FormatFileSize(formFile.Length),
                            SaveType = EnumFileSaveType.FTP,
                            FilePath = savePath.Replace(ftpUrl, "")
                        });
                    }
                    else
                    {
                        error.Add($"{formFile.FileName}");
                    }
                }
                if (error.Any())
                {
                    string errMsg = String.Join(',', error);
                    throw Oops.Oh($"附件{errMsg}上传失败！");
                }
                if (attachFiles.Any())
                {
                    await _repository.Insert(attachFiles);
                }
            }
            return attachFiles;
        }
        /// <summary>
        /// 上传单附件—Ftp存储
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<SysFile> UploadFtpFile(IFormFile formFile)
        {
            var configuration = App.Configuration;
            string ftpUrl = configuration["FileFtp:FtpUrl"];//App.GetConfig<string>("FileFtp:FtpUrl")
            string ftpUser = configuration["FileFtp:FtpUser"];
            string ftpPassWord = configuration["FileFtp:FtpPwd"];
            SysFile attachFile =null;//返回的附件上传结果
            if (formFile == null)
            {
                throw Oops.Oh("请选择需要上传的文件！");
            }
            else
            {
                string fileExtension = Path.GetExtension(formFile.FileName);//获取文件名称后缀                                                                                                 
                string savePath = "";
                var fileStream = formFile.OpenReadStream();
                bool saveResult = FileHelper.FTPUploadFile(fileStream, fileExtension, ftpUrl, ftpUser, ftpPassWord, out savePath);
                if (saveResult)
                {
                    attachFile = new SysFile()
                    {
                        FileName = formFile.FileName,
                        FileType = fileExtension,
                        FileSize = ToolUtil.FormatFileSize(formFile.Length),
                        SaveType = EnumFileSaveType.FTP,
                        FilePath = savePath.Replace(ftpUrl, "")
                    };
                }
                else
                {
                    throw Oops.Oh($"附件上传失败！");
                }
                if (attachFile!=null)
                {
                    await _repository.Insert(attachFile);
                }
            }
            return attachFile;
        }
        /// <summary>
        /// 通过附件id下载文件
        /// </summary>
        /// <param name="fileId">附件id</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> DownloadById(long fileId)
        {
            var fileInfo=await _repository.GetEntityById(fileId);
            string filePath=fileInfo.FilePath;
            string fileName=fileInfo.FileName;
            if (fileInfo.SaveType == EnumFileSaveType.FTP)
            {
                var configuration = App.Configuration;
                string ftpUrl = configuration["FileFtp:FtpUrl"];//App.GetConfig<string>("FileFtp:FtpUrl")
                string ftpUser = configuration["FileFtp:FtpUser"];
                string ftpPassWord = configuration["FileFtp:FtpPwd"];
                string ftpFullPath = ftpUrl + filePath;
                Stream fs=FileHelper.FTPDownloadFile(ftpFullPath, ftpUser, ftpPassWord);
                return new FileStreamResult(fs, "application/octet-stream") { FileDownloadName = fileName };
            }
            else
            {
                string fullPath = _environment.WebRootPath + filePath;
                return new FileStreamResult(new FileStream(fullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), "application/octet-stream") { FileDownloadName = fileName };
            }           
        }
        /// <summary>
        /// 本地存储文件下载
        /// </summary>
        /// <param name="url">附件路径（相对路径）</param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult DownloadFile(string url)
        {
            string webRootPath = _environment.WebRootPath;
            string filePath = webRootPath + url;
            return new FileStreamResult(new FileStream(filePath, FileMode.Open), "application/octet-stream") { FileDownloadName = Path.GetFileName(filePath) };
        }
        /// <summary>
        /// 本地存储文件下载(转码，用于文件中包含中文的文件)
        /// </summary>
        /// <param name="url">附件路径（相对路径）</param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult DownloadFileEncode(string url)
        {
            Encoding utf8 = Encoding.UTF8;
            url = HttpUtility.UrlDecode(url, utf8).Trim();//解码
            string webRootPath = _environment.WebRootPath;
            string filePath = webRootPath + url;
            return new FileStreamResult(new FileStream(filePath, FileMode.Open), "application/octet-stream") { FileDownloadName = Path.GetFileName(filePath) };
        }
    }
}
